from OWRpy import *
import redRi18n
_ = redRi18n.get_(package = 'base')

import signals 
import redRGUI 

class betadisper(OWRpy): 
    globalSettingsList = ['commit']
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        
        # Python variables
        self.data = {}
        self.RFunctionParam_object = ''
        self.RFunctionParam_diss = ''
        
        #Unique R variable
        self.setRvariableNames(['betadisper'])
        self.setRvariableNames(['anova_BD'])
        self.setRvariableNames(['permutest_BD'])
        self.setRvariableNames(['tukey_BD'])
        
        #Inputs
        self.inputs.addInput('id0', 'Group', signals.base.RDataFrame, self.processobject)
        self.inputs.addInput('id1', 'Dissimilarity', signals.base.RMatrix, self.processdiss) 

        #Outputs
        self.outputs.addOutput("id0","Betadisper", signals.base.RList)
        self.outputs.addOutput("id1","ANOVA", signals.base.RList)
        self.outputs.addOutput("id2","Permutation test", signals.base.RList)
        self.outputs.addOutput("id3","Tukey test", signals.base.RList)
        
        #GUI
        self.RFunctionParam_group = redRGUI.base.comboBox(self.controlArea, label = 'Select group column', callback=self.onGroupChange)

        ## Tabs
        self.RFunctionParam_GUI_tabs = redRGUI.base.tabWidget(self.controlArea)
        self.RFunctionParam_GUI_tabsStats = self.RFunctionParam_GUI_tabs.createTabPage(name = "Stats",orientation='vertical')
        self.RFunctionParam_GUI_tabsPCoA = self.RFunctionParam_GUI_tabs.createTabPage(name = "PCoA plot",orientation='vertical')
        self.RFunctionParam_GUI_tabsTukey = self.RFunctionParam_GUI_tabs.createTabPage(name = "Tukey HSD",orientation='vertical')
        self.RFunctionParam_GUI_tabsBoxplots = self.RFunctionParam_GUI_tabs.createTabPage(name = "Box plots",orientation='vertical')

        ## Stats
        self.RoutputWindow_anova = redRGUI.base.textEdit(self.RFunctionParam_GUI_tabsStats, label = 'ANOVA')
        self.RFunctionParam_GUI_permutestBox=redRGUI.base.groupBox(self.RFunctionParam_GUI_tabsStats, label = 'Permutation test for F')
        self.RFunctionParam_permutestPairwise = redRGUI.base.radioButtons(self.RFunctionParam_GUI_permutestBox,  label = "Pairwise", buttons = [('FALSE', 'No'),('TRUE','Yes')],
        setChecked='TRUE',orientation='horizontal')
        self.RoutputWindow_permutest = redRGUI.base.textEdit(self.RFunctionParam_GUI_permutestBox, label = 'Permutation test for F', displayLabel = False)
        
        ## PCoA
        self.plotAreaPCoA = redRGUI.plotting.redRPlot(self.RFunctionParam_GUI_tabsPCoA, label = "PCoA", displayLabel = False)
        
        ## Tukey
        self.RFunctionParam_tukeyOrdered = redRGUI.base.radioButtons(self.RFunctionParam_GUI_tabsTukey,  label = "Ordered", buttons = [('FALSE', 'No'),('TRUE','Yes')],
        setChecked='FALSE',orientation='horizontal')
        self.RFunctionParam_tukeyConfLevel = redRGUI.base.lineEdit(self.RFunctionParam_GUI_tabsTukey, label = 'Family-wise confidence level', text = '0.95')
        self.RFunctionParam_GUI_tukeytabs = redRGUI.base.tabWidget(self.RFunctionParam_GUI_tabsTukey)
        self.RFunctionParam_GUI_tukeytabsPlot = self.RFunctionParam_GUI_tukeytabs.createTabPage(name = "Plot",orientation='vertical')
        self.RFunctionParam_GUI_tukeytabsResults = self.RFunctionParam_GUI_tukeytabs.createTabPage(name = "Results",orientation='vertical')
        self.plotAreaTukey = redRGUI.plotting.redRPlot(self.RFunctionParam_GUI_tukeytabsPlot, label = "Tukey", displayLabel = False)
        self.RoutputWindow_tukey = redRGUI.base.textEdit(self.RFunctionParam_GUI_tukeytabsResults, label = 'Tukey', displayLabel = False)
        
        ## Box plots
        self.plotAreaBoxplots = redRGUI.plotting.redRPlot(self.RFunctionParam_GUI_tabsBoxplots, label = "Boxplots of the distances to centroid")
                
        #Commit
        self.commit = redRGUI.base.commitButton(self.bottomAreaRight, _("Commit"), alignment=Qt.AlignLeft, 
        callback = self.commitFunction, processOnInput=True)
        
    def onGroupChange(self):
        self.R('groups<-levels(as.factor('+unicode(self.RFunctionParam_object)+'$'+unicode(self.RFunctionParam_group.currentId())+'))')
        if len(self.R('groups')) > 7 :
            self.status.setText('WARNING: The selected column contains a lot of groups ('+str(len(self.R('groups')))+'). Computations might be long. Are you sure the right column is selected?')
        else:
            self.status.setText('The selected column contains '+str(len(self.R('groups')))+' groups.')
        
    def processobject(self, data):
        if not self.require_librarys(["vegan"]):
            self.status.setText('R Libraries Not Loaded.')
            return
        if data:
            self.RFunctionParam_object=data.getData()
            self.data = data
            self.RFunctionParam_group.update(self.R('names('+self.RFunctionParam_object+')', wantType = 'list'))
            if self.commit.processOnInput():
                self.commitFunction()
        else:
            self.RFunctionParam_clust=''
            
    def processdiss(self, data):
        if not self.require_librarys(["vegan"]):
            self.status.setText('R Libraries Not Loaded.')
            return
        if data:
            self.RFunctionParam_diss=data.getData()
            self.data = data
            if self.commit.processOnInput():
                self.commitFunction()
        else:
            self.RFunctionParam_clust=''
            
    def commitFunction(self):
        if unicode(self.RFunctionParam_diss) == '':
            self.status.setText('No dissimilarity data.')
            return
        if unicode(self.RFunctionParam_object) == '':
            self.status.setText('No group data.')
            return
        
        # betadisper
        self.R(self.Rvariables['betadisper']+'<-betadisper(d='+unicode(self.RFunctionParam_diss)+', group='+unicode(self.RFunctionParam_object)+'$'+unicode(self.RFunctionParam_group.currentId())+')' )
        
        # anova
        self.R(self.Rvariables['anova_BD']+'<-anova('+self.Rvariables['betadisper']+')')
        self.R('txt<-capture.output('+self.Rvariables['anova_BD']+')', wantType = 'NoConversion')
        self.RoutputWindow_anova.clear()
        tmp = self.R('paste(txt, collapse ="\n")')
        self.RoutputWindow_anova.insertHtml('<br><pre>'+tmp+'</pre>')
        
        # permutest F        
        self.R(self.Rvariables['permutest_BD']+'<-permutest('+self.Rvariables['betadisper']+', pairwise='+unicode(self.RFunctionParam_permutestPairwise.getCheckedId())+')')
        self.R('txt<-capture.output('+self.Rvariables['permutest_BD']+')', wantType = 'NoConversion')
        self.RoutputWindow_permutest.clear()
        tmp = self.R('paste(txt, collapse ="\n")')
        self.RoutputWindow_permutest.insertHtml('<br><pre>'+tmp+'</pre>')
        
        # PCoA
        self.plotAreaPCoA.plotMultiple(query = self.Rvariables['betadisper'], function = 'plot.betadisper', layers = ['legend(x="topright", legend=groups, pch=1:length(groups))'])
        #for i in range(1,len(levels)): # this was to add text labels on blobs
        #    self.plotAreaPCoA.plotMultiple(query = 'labels="'+levels[i]+'", x='+self.Rvariables['betadisper']+'$centroids['+unicode(i)+',1], y='+self.Rvariables['betadisper']+'$centroids['+unicode(i)+',2]', function = 'text')
        
        # Tukey
        self.R(self.Rvariables['tukey_BD']+'<-TukeyHSD('+self.Rvariables['betadisper']+', ordered='+unicode(self.RFunctionParam_tukeyOrdered.getCheckedId())+', conf.level='+unicode(self.RFunctionParam_tukeyConfLevel.text())+')')
        self.R('txt<-capture.output('+self.Rvariables['tukey_BD']+')', wantType = 'NoConversion')
        self.RoutputWindow_tukey.clear()
        tmp = self.R('paste(txt, collapse ="\n")')
        self.RoutputWindow_tukey.insertHtml('<br><pre>'+tmp+'</pre>')
        self.plotAreaTukey.plotMultiple(query = self.Rvariables['tukey_BD'], function = 'plot')
        
        # Boxplots
        self.plotAreaBoxplots.plotMultiple(query = self.Rvariables['betadisper'], function = 'boxplot')
        
        # Output
        self.rSend("id0", signals.base.RList(self, data = self.Rvariables["betadisper"], checkVal=False))
        self.rSend("id1", signals.base.RList(self, data = self.Rvariables["anova_BD"], checkVal=False))
        self.rSend("id2", signals.base.RList(self, data = self.Rvariables["permutest_BD"], checkVal=False))
        self.rSend("id3", signals.base.RList(self, data = self.Rvariables["tukey_BD"], checkVal=False))
        
        
        